package com.duoduo.common.api.myinterface;


import com.duoduo.common.api.spi.extension.SPI;

import java.io.Serializable;
import java.util.Map;

/**缓存操作接口
 * @author duoduo
 *
 */
@SPI
public interface CacheOperator {

	/**根据key获取缓存数据
	 * @param appName
	 * @param key
	 * @return
	 */
	public String get(String prefixName, String appName, String key);

	/**根据key获取缓存数据
	 * @param appName
	 * @param key
	 * @param clazz
	 * @return
	 */
	public <T extends Serializable> T getObjImplSeri(String prefixName, String appName, String key, Class<T> clazz);

	/**根绝key删除缓存数据
	 * @param appName
	 * @param key
	 * @return
	 */
	public Long delKey(String prefixName, String appName, String key);

	/**设置缓存数据
	 * @param appName
	 * @param key
	 * @param value
	 * @param expire
	 * @return
	 */
	public String set(String prefixName, String appName, String key, String value, int expire);

	/**设置缓存数据
	 * @param appName
	 * @param key
	 * @param value
	 * @param expire
	 * @return
	 */
	public <T extends Serializable> String setImplSeri(String prefixName, String appName, String key, T value, int expire);

	/**对存储的key的数值执行原子（跨JVM）的加1操作
	 *
	 * @param appName
	 * @param key key
	 * @return 执行递增操作后key对应的值
	 */
	public long incr(String prefixName, String appName, String key);

	/**对存储的key的数值执行原子（跨JVM）的加1操作
	 *
	 * @param appName
	 * @param key key
	 * @return 执行递增操作后key对应的值
	 */
	public long decr(String prefixName, String appName, String key);

	/**判断key是否存在
    *
    * @param key key
    * @return true存在，false不存在
    */
	public Boolean exists(String prefixName, String appName, String key);

	/**判断key是否存在
    *
    * @param key key
    * @return true存在，false不存在
    */
	public Boolean existsSeri(String prefixName, String appName, String key);

	public Long hincrBy(String prefixName, String appName, String key, String field, Long value);
	
	/**
     * 将哈希表 key中的域field的值设为 value.<br>
     * 如果key不存在,将新建一个哈希表.<br>
     * 如果域field已经存在于哈希表中,旧值将被覆盖.<br>
     * 时间复杂度: O(1)
     *
     * @param key key
     * @param field 域
     * @param value value
     * @return 如果field是哈希表中的一个新建域,并且值设置成功,返回 1. 如果哈希表中域field已经存在且旧值已被新值覆盖,返回 0.
     */
	public Long hashSet(String prefixName, String appName, String key, String field, String value);

	/**
     * 将哈希表 key中的域field的值设为 value,同时设置哈希表key的有效期.<br>
     * 如果key不存在,将新建一个哈希表.<br>
     * 如果域field已经存在于哈希表中,旧值将被覆盖.<br>
     * 时间复杂度: O(1)
     *
     * @param key key
     * @param field 域
     * @param value value
     * @param expire 有效期（秒）
     * @return 如果field是哈希表中的一个新建域,并且值设置成功,返回 1.如果哈希表中域field已经存在且旧值已被新值覆盖,返回 0.异常返回null
     */
	public Long hashSet(String prefixName, String appName, String key, String field, String value, int expire);

	/**
     * 返回哈希表key中给定域 field的值.<br>
     * 时间复杂度:O(1)
     *
     * @param key key
     * @param field 域
     * @return 给定域的值.当给定域不存在或是给定 key不存在时,返回 nil .
     */
	public String hashGet(String prefixName, String appName, String key, String field);

	public <T extends Serializable> Long hashSetImplSeri(String prefixName, String appName, String key, String field, T value);

	public <T extends Serializable> Long hashSetImplSeri(String prefixName, String appName, String key, String field, T value, int expire);

	public <T extends Serializable> T hashGetImplSeri(String prefixName, String appName, String key, String field, Class<T> clazz);

	public Map<String, String> hashGetAll(String prefixName, String appName, String key);

	public <T extends Serializable> Map<String, T> hashGetAllImplSeri(String prefixName, String appName, String key, Class<T> clazz);

	public Long listPushTail(String prefixName, String appName, String key, String... values);
	
	@SuppressWarnings("unchecked")
	public <T extends Serializable> Long listPushTailImplSeri(String prefixName, String appName, String key, T... values);

	public Long listPushHead(String prefixName, String appName, String key, String... values);
	
	@SuppressWarnings("unchecked")
	public <T extends Serializable> Long listPushHeadImplSeri(String prefixName, String appName, String key, T... values);

	public String listPop(String prefixName, String appName, String key);
	
	public <T extends Serializable> T listPopImplSeri(String prefixName, String appName, String key, Class<T> clazz);

}
